.text
.align 8
.section .rodata
.LC0:
	.string	"Enter name of destination file:"
.LC1:
	.string	"a+"
.LC2:
	.string	"Cannot open %s\n"
.LC3:
	.string	"Cannot create output buffer\n"
.LC4:
	.string	"Enter name of first source file (empty line to quit):"
.LC5:
	.string	"Cannot append file to itself\n"
.LC6:
	.string	"r"
.LC7:
	.string	"Cannot create input buffer\n"
.LC8:
	.string	"Error in reading file %s.\n"
.LC9:
	.string	"Error in writing file %s.\n"
.LC10:
	.string	"File %s appended.\n"
.LC11:
	.string	"Next file (empty line to quit):"
.LC12:
	.string	"Done appending.%d files appended.\n"
.LC13:
	.string	"%s contents:\n"
.LC14:
	.string	"Done displaying."

.text
.globl main
.type main, @function
main:
    addi sp, sp, -208
    sd ra, 200(sp)
    sd s0, 192(sp)

    addi s0, sp, 192
    // 分配局部变量
    // fa: -8(s0) /* fa */
    // fs: -16(s0) /* fs */
    // files: -20(s0) /* files */
    // file_app: -101(s0) /* file_app */
    // file_src: -182(s0) /* file_src */
    // ch: -186(s0) /* ch */
    lw zero, -20(s0) /* files */

    lui a5, %hi(.LC0)
    addi a0, a5, %lo(.LC0)
    call puts

    addi a0, s0, -101 /* offset of file_app */
    li a1, 81
    call s_gets

    addi a0, s0, -101 /* offset of file_app */
    lui a5, %hi(.LC1)
    addi a1, a5, %lo(.LC1)
    call fopen
    sd a0, -8(s0) /* fa */
    bne a0, zero, .APPEND_FILE_OPENED
    lui a5, %hi(stderr)
    addi a5, a5, %lo(stderr)
    ld a0, 0(a5)
    lui a5, %hi(.LC2)
    addi a1, a5, %lo(.LC2)
    addi a2, s0, -101 /* offset of file_app */
    call fprintf
    li a0, 1
    call exit
.APPEND_FILE_OPENED:
    ld a0, -8(s0) /* fa */
    mv a1, zero
    mv a2, zero
    li a3, 4096
    call setvbuf
    sext.w a5, a0
    beq a5, zero, .APPEND_FILE_SETVBUF_SUCCESS
    lui a5, %hi(.LC3)
    addi a0, a5, %lo(.LC3)
    lui a5, %hi(stderr)
    addi a5, a5, %lo(stderr)
    ld a1, 0(a5)
    call fputs
    li a0, 1
    call exit
.APPEND_FILE_SETVBUF_SUCCESS:
    lui a5, %hi(.LC4)
    addi a0, a5, %lo(.LC4)
    call puts
    j .WHILE_31_COMPARE
.WHILE_31_ENTER:
    addi a0, s0, -182 /* offset of file_src */
    addi a1, s0, -101 /* offset of file_app */
    call strcmp
    sext.w a5, a0
    beq a5, zero, .SRC_APP_SAME

    addi a0, s0, -182 /* offset of file_src */
    lui a5, %hi(.LC6)
    addi a1, a5, %lo(.LC6)
    call fopen
    sd a0, -16(s0) /* fs */
    beq a0, zero, .OPEN_SRC_FILE_FAILED

    ld a0, -16(s0) /* fs */
    mv a1, zero
    mv a2, zero
    li a4, 4096
    call setvbuf
    sext.w a5, a0
    bne a5, zero, .SRC_FILE_SETVBUF_FAILED

    ld a0, -16(s0) /* fs */
    ld a1, -8(s0) /* fa */
    call append

    ld a0, -16(s0) /* fs */
    call ferror
    sext.w a5, a0
    bne a5, zero, .FERROR_FS
    j .CHECK_FA
.FERROR_FS:
    lui a5, %hi(stderr)
    ld a0, %lo(stderr)(a5)
    lui a5, %hi(.LC8)
    addi a1, a5, %lo(.LC8)
    addi a2, a0, -182 /* offset of file_src */
    call fprintf
.CHECK_FA:
    ld a0, -8(s0) /* fa */
    call ferror
    sext.w a5, a0
    bne a5, zero, .FERROR_FA
    j .FILE_CLOSE
.FERROR_FA:
    lui a5, %hi(stderr)
    ld a0, %lo(stderr)(a5)
    lui a5, %hi(.LC9)
    addi a1, a5, %lo(.LC9)
    addi a2, a0, -101 /* offset of file_app */
    call fprintf
.FILE_CLOSE:
    ld a0, -16(s0) /* fs */
    call fclose

    lw a5, -20(s0) /* files */
    addiw a5, a5, 1
    sd a5, -20(s0) /* files */

    lui a5, %hi(.LC10)
    addi a0, a5, %lo(.LC10)
    addi a1, s0, -182 /* offset of file_src */
    call printf

    lui a5, %hi(.LC11)
    addi a0, a5, %lo(.LC11)
    call puts
    j .WHILE_31_INCR
.SRC_FILE_SETVBUF_FAILED:
    lui a5, %hi(.LC7)
    addi a0, a5, %lo(.LC7)
    lui a5, %hi(stderr)
    ld a1, %lo(stderr)(a5)
    call fputs
    j .WHILE_31_INCR
.OPEN_SRC_FILE_FAILED:
    lui a5, %hi(stderr)
    ld a0, %lo(stderr)(a5)
    lui a5, %hi(.LC2)
    addi a1, a5, %lo(.LC2)
    addi a2, s0, -182 /* offset of file_src */
    call fprintf
    j .WHILE_31_INCR
.SRC_APP_SAME:
    lui a5, %hi(.LC5)
    addi a0, a5, %lo(.LC5)
    lui a5, %hi(stderr)
    ld a1, %lo(stderr)(a5)
    call fputs
    j .WHILE_31_INCR
.WHILE_31_INCR:
    // nothing to do
.WHILE_31_COMPARE:
    addi a0, s0, -182 /* offset of file_src */
    li a1, 81
    call s_gets
    beq a0, zero, .WHILE_31_END
    addi a5, s0, -182 /* offset of file_src */
    lb a5, 0(a5)
    sext.b a5, a5
    beq a5, zero, .WHILE_31_END
    j .WHILE_31_ENTER
.WHILE_31_END:
    lui a5, %hi(.LC12)
    addi a0, a5, %lo(.LC12)
    lw a1, -20(s0) /* files */
    call printf
    ld a0, -8(s0) /* fa */
    call rewind
    lui a5, %hi(.LC13)
    addi a0, a5, %lo(.LC13)
    addi a1, s0, -101 /* offset of file_app */
    call printf

    j .WHILE_60_COMPARE
.WHILE_60_ENTER:
    lw a0, -186(s0) /* ch */
    call putchar
.WHILE_60_INCR:
    // nothing to do 
.WHILE_60_COMPARE:
    ld a0, -8(s0) /* fa */
    call getc
    sw a0, -186(s0) /* ch */
    sext.w a5, a0
    li a6, -1
    bne a5, a6, .WHILE_60_ENTER
.WHILE_60_END:
    lui a5, %hi(.LC14)
    addi a0, a5, %lo(.LC14)
    call puts
    ld a0, -8(s0) /* fa */
    call fclose
.EXIT_SUCCESS:
    mv a0, zero
    ld ra, 200(sp)
    ld s0, 192(sp)
    addi sp, sp, 208
    jr ra

// 这里相当于把append搞成static的了，因为没有.globl，也不需要.globl
.type append, @function
append:
    addi sp, sp, -48
    sd ra, 40(sp)
    sd s0, 32(sp)
    addi s0, sp, 32

    // 分配局部变量
    // source: -8(s0) /* source */
    // dest: -16(s0) /* dest */
    // bytes: -24(s0) /* bytes */
    sd a0, -8(s0) /* source */
    sd a1, -16(s0) /* dest */

    j .WHILE_71_COMPARE
.WHILE_71_ENTER:
    lui a5, %hi(temp.0)
    addi a0, a5, %lo(temp.0)
    li a1, 1
    ld a2, -24(s0) /* bytes */
    ld a3, -16(s0) /* dest */
    call fwrite
.WHILE_71_INCR:
.WHILE_71_COMPARE:
    lui a5, %hi(temp.0)
    addi a0, a5, %lo(temp.0)
    li a1, 1
    li a2, 4096
    ld a3, -8(s0) /* source */
    call fread
    sd a0, -24(s0) /* bytes */
    bgt a0, zero, .WHILE_71_ENTER

    ld ra, 40(sp)
    ld s0, 0(s0)
    addi sp, sp, 48
    jr ra 

.type s_gets, @function
s_gets:
    addi sp, sp, -48
    sd ra, 40(sp)
    sd s0, 32(sp)
    addi s0, sp, 32

    // 根据x86的经验，就不存参数了，按照通用的规矩是要存的
    // ret_val: -8(s0)
    // i: -12(s0)

    // 不行，不存参数是不行的，因为调用fgets后，返回值会把a0覆盖了。
    // st:-20(s0)
    // n: -24(s0)
    sd a0, -20(s0) /* st */
    sw a1, -24(s0) /* n */
    sw zero, -12(s0) /* i */

    // 以下两行实际不需要，不过协助这里，万一中间插了代码把a0和a1覆盖了呢
    ld a0, -20(s0) /* st */
    lw a1, -24(s0) /* n */
    lui a5, %hi(stdin)
    ld a2, %lo(stdin)(a5)
    call fgets

    sd a0, -8(s0) /* ret_val */
    beq a0, zero, .EXIT

    j .WHILE_15_COMPARE
.WHILE_15_ENTER:
    lw a5, -12(s0) /* i */
    addiw a5, a5, 1
    sw a5, -12(s0) /* i */
.WHILE_15_COMPARE:
    lw a5, -12(s0) /* i */
    sext.w a5, a5
    ld a4, -20(s0) /* st */
    add a5, a4, a5
    lbu a5, (a5)
    li a4, 10
    beq a5, a4, .IF_17
    bne a5, zero, .WHILE_15_ENTER
.IF_17:
    lw a5, -12(s0) /* i */
    sext.w a5, a5
    ld a4, -20(s0) /* st */
    add a5, a4, a5
    lbu a6, (a5)
    li a4, 10
    bne a6, a4, .WHILE_20_ENTER
    sb zero, (a5)
    j .EXIT
.WHILE_20_ENTER:
    call getchar
    li a5, 10
    bne a0, a5, .WHILE_20_ENTER
.EXIT:
    ld a0, -8(s0) /* ret_val */
    ld ra, 40(sp)
    ld s0, 32(sp)
    addi sp, sp, 48
    jr ra
.local temp.0
// 不太明白，后面有个32是什么意思，我给它去掉，看看会不会有问题
// .comm temp.0,4096,32
.comm temp.0,4096